package ppu

type AddrRegister struct {
	Value [2]byte
	HiPtr bool
}

func NewAddrRegister() *AddrRegister {
	return &AddrRegister{
		Value: [2]byte{0, 0},
		HiPtr: true,
	}
}

func (a *AddrRegister) Set(data uint16) {
	a.Value[0] = byte(data >> 8)
	a.Value[1] = byte(data & 0xFF)
}

func (a *AddrRegister) Update(data byte) {
	if a.HiPtr {
		a.Value[0] = data
	} else {
		a.Value[1] = data
	}

	if a.Get() > 0x3FFF {
		a.Set(a.Get() & 0b11111111111111)
	}

	a.HiPtr = !a.HiPtr
}

// Get returns the 16-bit value of the register
func (a *AddrRegister) Get() uint16 {
	return uint16(a.Value[0])<<8 | uint16(a.Value[1])
}

// Increment increments the register by 1
func (a *AddrRegister) Increment(inc uint8) {
	lo := a.Value[1]
	a.Value[1] += inc

	if lo > a.Value[1] {
		a.Value[0]++
	}

	if a.Get() > 0x3FFF {
		a.Set(a.Get() & 0b11111111111111)
	}
}

// ResetLatch resets the hi/lo pointer
func (a *AddrRegister) ResetLatch() {
	a.HiPtr = true
}
